package com.gan.simple_init.config;


import com.gan.simple_init.common.filter.JwtAuthenticationTokenFilter;
import com.gan.simple_init.common.filter.PermitUrlProperties;
import com.gan.simple_init.common.filter.RestAuthorizationEntryPoint;
import com.gan.simple_init.common.filter.RestfulAccessDeniedHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/**
 * security配置类
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {


    /**
     * 自定义用户未登陆处理
     */
    @Resource
    private RestAuthorizationEntryPoint restAuthorizationEntryPoint;

    /**
     * 自定义用户权限不足处理
     */
    @Resource
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;

    /**
     * 自定义接口白名单
     */
    @Resource
    private PermitUrlProperties permitUrlProperties;


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());

    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {


        httpSecurity
                // 关闭跨站请求防护及不使用session
                .csrf()
                .disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().antMatcher("/**").authorizeRequests()
                // 放行相关路径
                .antMatchers(permitUrlProperties.getPermits()).permitAll()
                .and()
                //自定义权限拒绝处理类
                .exceptionHandling()
                // 自定义用户权限不足
                .accessDeniedHandler(restfulAccessDeniedHandler)
                // 自定义用户未登陆处理
                .authenticationEntryPoint(restAuthorizationEntryPoint)
                // 任何请求都需要身份认证
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and().formLogin().loginProcessingUrl("/login")
                // 自定义权限拦截JWT过滤器
                .and()
                .addFilterAt(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class)
                // 禁用缓存
                .headers()
                .cacheControl();

        //允许跨域
        httpSecurity.cors();
    }


    /**
     * 将PasswordEncoder注入到spring容器中
     * 配置使用bcrypt加密
     *
     * @return 返回加密方式
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * 将JwtAuthenticationTokenFilter注入到spring容器中
     */
    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter();
    }
}
